﻿using UnityEngine;
using System.Collections.Generic;
using LitJson;


using VFramework;
using System;

namespace VFramework
{
	/// <summary>
	/// 挂载在unity3d中的object，用于处理接受到的机器指令
	/// 以及管理发送和发送回调，接收回调等，单例的存在，写法上有点怪异
	/// 
	/// 主要思路是发送消息时，绑定一个回调在消息的id上，收的的消息为该id时候，invoke该回调，并删除之。
	/// 
	/// 2016年06月08日10:49:55 蒋利武
	/// </summary>
	public class MachineObject : MonoBehaviour
	{

		public delegate void MachineCB ();

		/// <summary>
		/// 服务器主动发送消息，程序注册的相关回调，不删除
		/// </summary>
		public Dictionary<int, MachineCB> fCallBacks;

		/// <summary>
		/// 大按钮的
		/// </summary>
		public const int BIG_MIDDLE_BTN_ID = 19;


		private static MachineObject _instance;
		private object mutex = new object ();

		/// <summary>
		/// 发送消息时，临时保存的回调
		/// </summary>
		private Dictionary<int, MachineCmd> tmpCallbacks;
		private Queue<JsonData> machineMsgs;




		void Awake ()
		{
			_instance = this;
			tmpCallbacks = new Dictionary<int, MachineCmd> ();
			machineMsgs = new Queue<JsonData> ();
			fCallBacks = new Dictionary<int, MachineCB> ();
		}

		/// <summary>
		/// 发送消息时，临时保存回调
		/// </summary>
		/// <returns>The tmp callback.</returns>
		/// <param name="id">Identifier.</param>
		/// <param name="cmd">Cmd.</param>
		public static void pushTmpCallback (int id, MachineCmd cmd)
		{
			lock (_instance.mutex) {
				if (_instance.tmpCallbacks.ContainsKey (id)) {
					_instance.tmpCallbacks.Remove (id);
				}

				_instance.tmpCallbacks.Add (id, cmd);
			}
		}

		/// <summary>
		/// 注册系统消息回调
		/// </summary>
		/// <returns>The callback.</returns>
		/// <param name="id">消息id</param>
		/// <param name="cb">回调</param>
		public static void pushCallback (int id, MachineCB cb)
		{
			_instance.fCallBacks.Add (id, cb);
		}

		/// <summary>
		/// 收到消息了，放入队列中
		/// </summary>
		/// <returns>The machine message.</returns>
		/// <param name="data">Data.</param>
		public static void pushMachineMsg (JsonData data)
		{
			lock (_instance.mutex) {
				_instance.machineMsgs.Enqueue (data);
			}
		}


		/// <summary>
		/// 改变颜色
		/// </summary>
		/// <returns></returns>
		/// <param name="r">The red component.</param>
		/// <param name="g">The green component.</param>
		/// <param name="b">The blue component.</param>
		public static void changColor (int r, int g, int b)
		{
			MController.g ().sendCmd (new MachineCmd (1, new System.Collections.Generic.List<int> {
			r, g, b
		}, delegate (LitJson.JsonData data) {

		}));
		}

		/// <summary>
		/// 清理
		/// </summary>
		public static void release ()
		{
			_instance.fCallBacks.Clear ();
		}

		void processMsg (JsonData data)
		{
			try {

				VLogger.debug ("[Machine reci msg]:" + data.ToJson ());
				int id = (int)data ["id"];

				if (tmpCallbacks.ContainsKey (id)) {
					tmpCallbacks [id].getCB ().Invoke (data);
					tmpCallbacks.Remove (id);  //回调完后就删除 
				}

				if (fCallBacks.ContainsKey (id)) {
					fCallBacks [id].Invoke ();
				}
			} catch (Exception e) {
				VLogger.error (e.ToString ());
			}
		}

		void Update ()
		{
			lock (mutex) {
				if (machineMsgs != null && machineMsgs.Count > 0) {
					processMsg (machineMsgs.Dequeue ());  //每帧处理一条
				}
			}
		}

	}

}